const MAX_NOT_LAZY = 12; // 最大无需懒加载封面数
const DATA_CACHE = []; // 数据缓存

let cate_how_id = [];
let cate_how_name = [];
let cate_what_id = [];
let cate_what_name = [];
let last_load_more = 0; // 上次加载时封面存量
let timer_cate_how_id = null; // 分类按钮响应计时器ID
let timer_cate_what_id = null; // 分类按钮响应计时器ID
// let observer_loaded = null; // 图片列表观察器

$(document).ready(function() {
  initNav();
  init();
  load();
  checkAccount();
});

function init() {
  $(window).on("scroll", function() { // 监听页面滚动，刷新缩略图
    refresh();
  });
  $(".copyright a:first").click(function() { // 点击一言即可刷新
    refreshGlitter();
  });
  if (PAGE_CURRENT === "/favorite" && PROVIDER_ID !== "snake") { // 非“故纸堆”收藏增加跳转提示
    showToastInfo("favorite", `以下仅为你在「${PROVIDER_NAME}」的收藏。`, "查看全站收藏", function() {
      let url = new URL(location.href);
      url.host = url.host.replace(/^.+?(?=\.)/, "snake");
      // location.replace(url); // 不会记入历史页面（不可回退）
      location.assign(url.href); // 记入历史页面（可回退）
    });
  }
  // $(".navbar-more").addClass("navbar-more-visible"); // 显示”关于“入口
  // if (PAGE_CURRENT === "/favorite") {
  //   // observer_loaded = new MutationObserver(function() {
  //   //   observer_loaded.disconnect(); // 注销观察器
  //   //   setTimeout(function() {
  //   //     checkAccount();
  //   //   }, 400);
  //   // });
  //   // observer_loaded.observe($(".image-list-latest")[0], {childList: true});
  //   setTimeout(function() {
  //     checkAccount();
  //   }, 1000);
  // }
  showToastInfo("qc1", "今日图审：审图数……；累计：……", "查看统计", function() {
    qcStats();
  });
}

function initNav() {
  if (!isPageGuide()) { // 页眉标签名默认显示”拾光壁纸“，非引导页则追加显示当前图源名
    $(".navbar-brand span:eq(0)").html(`&nbsp;&#xb7;&nbsp;${PROVIDER_NAME_SHORT}`);
    $(".navbar-brand span:eq(1)").html(`&nbsp;&#xb7;&nbsp;${PROVIDER_NAME}`);
  }
  $(`.navbar-item[href='${PAGE_CURRENT}']`).addClass("navbar-here"); // 高亮当前页面页眉标签
  // 导航栏排序项和菜单项的控制事件
  // $("#btn-toggle-sort i").on("transitionend", function() { // 开关按钮隐藏动画辅助
  //   if ($(this).css("opacity") === "0") {
  //     $(this).parent().addClass("collapsed");
  //     $("#btn-toggle-menu").removeClass("collapsed");
  //     $("#btn-toggle-menu i").css("opacity", 1).css("transform", "translate(0, 0)");
  //   }
  // });
  // $("#btn-toggle-menu i").on("transitionend", function() { // 开关按钮隐藏动画辅助
  //   if ($(this).css("opacity") === "0") {
  //     $(this).parent().addClass("collapsed");
  //     $("#btn-toggle-sort").removeClass("collapsed");
  //     $("#btn-toggle-sort i").css("opacity", 1).css("transform", "translate(0, 0)");
  //   }
  // });
  $("#btn-toggle-sort").click(function() {
    $(".navbar-sort").removeClass("collapsed");
    $(".navbar-menu").addClass("collapsed");
    $(this).addClass("collapsed");
    $("#btn-toggle-menu").removeClass("collapsed");
    // $(this).children("i").css("opacity", 0).css("transform", "translate(8px, 0)");
  });
  $("#btn-toggle-menu").click(function() {
    $(".navbar-menu").removeClass("collapsed");
    $(".navbar-sort").addClass("collapsed");
    $(this).addClass("collapsed");
    $("#btn-toggle-sort").removeClass("collapsed");
    // $(this).children("i").css("opacity", 0).css("transform", "translate(-8px, 0)");
  });
  // Windows 平台推荐客户端
  if (navigator.userAgent.indexOf("Win64") >= 0) {
    let menu_client = $("<a class=\"navbar-item navbar-menu navbar-more collapsed\"></a>");
    menu_client.text("桌面版")
        .attr("href", "https://www.microsoft.com/store/apps/9N7VHQ989BB7")
        .attr("target", "_blank");
    $("#btn-bind").after(menu_client);
  }
}

function load() {
  let promise_arr = [fetch(generateApiUrl(URL_API, SPLIT_KEY, DATA_CACHE))];
  if (URL_API_CATE_HOW && cate_how_id.length === 0) { // 不显示分类或分类已加载，则无需加载分类信息
    promise_arr.push(fetch(URL_API_CATE_HOW));
  }
  if (URL_API_CATE_WHAT && cate_what_id.length === 0) { // 不显示分类或分类已加载，则无需加载分类信息
    promise_arr.push(fetch(URL_API_CATE_WHAT));
  }
  Promise.all(promise_arr)
    .then(response_arr => Promise.all(response_arr.map(response => response.json())))
    .then(data_arr => {
      for (let i = 1; i < data_arr.length; ++i) {
        handleDataCate(data_arr[i]);
      } // 必须先处理分类数据
      handleData(data_arr[0]);
    })
    .catch(err => {
      showToastError("load", err);
    });
}

function handleData(data) {
  if (!data || data["status"] !== 1) {
    showToastError("load", data ? data["msg"] : "接口数据异常");
    return;
  }
  logTotal(data["stats"], data["count"]);
  if (SHUFFLE) { // 打乱顺序
    data["data"].sort(() => Math.random() - 0.5);
  }
  let data_img = data["data"];
  if (isPageGuide()) { // 引导页中本图源封面固定在头部（记得去重）
    for (let item of data_img) {
      if (new URL(item["srcurl"]).hostname === location.hostname) {
        data_img.unshift(item);
        break;
      }
    }
  } else { // 非引导页若来自引导页，则将引导页封面固定在头部（记得去重）
    if (data["extend"] && data["extend"]["status"] === 1 && data["extend"]["data"].length > 0) {
      data["extend"]["data"][0]["extend"] = true; // 增加辅助字段标记来源，避免干扰分页参数计算
      data_img.unshift(data["extend"]["data"][0]);
    }
  }
  if (DATA_CACHE.length === 0) { // 清空占位
    $(".image-list").empty();
  }
  // DATA_CACHE.push(...data_img); // 缓存
  data_img.forEach(item => { // 去重缓存
    item["id"] = item["id"].toString(); // 重要：统一按 string 处理ID
    if (!DATA_CACHE.map(a => a["id"]).includes(item["id"])) {
      DATA_CACHE.push(item);
    }
  });
  if (DATA_CACHE.length === 0) {
    showToastError("load", data["msg"] ? data["msg"] : ("空空如也：" + location.pathname));
  }
  fill(DATA_CACHE);
  refresh();
}

function handleDataCate(data) {
  if (!data || data["status"] !== 1) {
    showToastError("load", data ? data["msg"] : "接口数据异常");
    return;
  }
  let data_cate = data["data"];
  data_cate.sort((a, b) => a["count"] - b["count"]); // 升序排列
  for (let item of data_cate) {
    if (item["version"] === "how") {
      if (item["id"] === "general") { // 其他 general 项始终固定到末尾
        cate_how_id.push(item["id"]);
        cate_how_name.push(item["name"]);
      } else {
        cate_how_id.splice(0, 0, item["id"]);
        cate_how_name.splice(0, 0, item["name"]);
      }
    } else if (item["version"] === "what") {
      if (item["id"] === "general") { // 其他 general 项始终固定到末尾
        cate_what_id.push(item["id"]);
        cate_what_name.push(item["name"]);
      } else {
        cate_what_id.splice(0, 0, item["id"]);
        cate_what_name.splice(0, 0, item["name"]);
      }
    }
  }
}

function fill(data) {
  let data_group = group(data);
  // let data_filled = $(".image-list img").map(() => $(this).attr("id")).toArray(); // this 将指向 window
  let data_filled = $(".image-list img").map(function() {
    return $(this).attr("id");
  }).toArray(); // 已展示图片ID
  // 配置组1
  let data_latest_todo = [];
  data_group[0].forEach(item => {
    if (!data_filled.includes(item["id"].toString())) {
      data_latest_todo.push(item);
    }
  });
  for (let i in data_latest_todo) { // 填充组1
    if ($(".image-list figure").length >= PAGE_TOTAL) { // 控量，不要将 $(".image-list img") 赋为变量使用
      break;
    }
    $(".image-list-latest").append(generateImgFigure(data_latest_todo[i], i > MAX_NOT_LAZY));
  }
  // 配置组2（默认隐藏）
  let data_earlier_todo = [];
  data_group[1].forEach(item => {
    if (!data_filled.includes(item["id"])) {
      data_earlier_todo.push(item);
    }
  });
  for (let i in data_earlier_todo) { // 填充组2
    if ($(".image-list figure").length >= PAGE_TOTAL) { // 控量，不要将 $(".image-list img") 赋为变量使用
      break;
    }
    $(".image-list-earlier").append(generateImgFigure(data_earlier_todo[i], i > MAX_NOT_LAZY));
  }
  if (data_group[1].length > 0) { // 显示组2
    let date_latest = data_group[0][data_group[0].length - 1]["reldate"]; // 组1最远日期
    $(".list-label-earlier span").text(parseLabelEarlier(date_latest));
    $(".list-label-earlier").removeClass("collapsed");
    $(".image-list-earlier").removeClass("collapsed");
  }
}

function refresh() {
  let imgs = $(".image-list img");
  let count_all = imgs.length; // 图片数（封面已加载+封面未加载）
  let count_not_refresh = 0; // 图片数（封面未加载）
  imgs.each(function() { // 加载封面
    // 已加载，跳过
    if (!$(this).data("thumb")) {
      return;
    }
    // 可见，加载
    if ($(window).height() + $(window).scrollTop() >= $(this).offset().top) {
      // $(this).attr("src", $(this).data("thumb"));
      // $(this).removeData("thumb");
      showThumb($(this));
    } else {
      count_not_refresh++;
    }
  });
  if (count_all < PAGE_TOTAL) { // 未达页容量，允许加载更多
    if (count_not_refresh === 0 && count_all > 0) { // 已滚动至页末，可加载更多
      if (count_all > last_load_more) { // 当前加载量未曾尝试加载更多，开始加载
        last_load_more = count_all; // 记录加载量
        if (SPLIT_KEY) { // 支持分页
          load();
        }
      }
    }
  }
  let copyright = $(".copyright");
  if (count_all > 0) { // 激活页脚
    copyright.removeClass("collapsed");
    if ($(window).height() + $(window).scrollTop() >= copyright.offset().top) { // 当前可见
      if (!copyright.data("visible")) { // 之前不可见
        copyright.data("visible", true);
        refreshGlitter();
      }
    } else {
      copyright.data("visible", false);
    }
  }
}

function group(data) {
  data = data ?? [];
  if (!PAGE_GROUP || data.length === 0) { // 已配置不分组，或无数据不分组
    return [data, []];
  }
  let date_latest = data[0]["reldate"];
  let index_earlier = 0;
  while (++index_earlier < data.length) { // 单日搜索
    if (data[index_earlier]["reldate"] !== date_latest) {
      break;
    }
  }
  // if (index_earlier > GROUP_TOTAL_OF_DAY) { // 近期单日量过大，不分组
  //   return [data, []];
  // }
  if (data.length > GROUP_TOTAL_OF_DAYS && index_earlier < data.length && index_earlier < GROUP_TOTAL_OF_DAYS) { // 近期单日量过小，按日追加
    let index_earlier_tmp = index_earlier;
    do {
      index_earlier = index_earlier_tmp;
      date_latest = data[index_earlier]["reldate"];
      while (++index_earlier_tmp < data.length) { // 继续搜索
        if (data[index_earlier_tmp]["reldate"] !== date_latest) {
          break;
        }
      }
    } while (index_earlier_tmp < GROUP_TOTAL_OF_DAYS);
  }
  let data_latest = [];
  let data_earlier = [];
  data.forEach((item, i) => {
    if (i < index_earlier) {
      data_latest.push(item);
    } else {
      data_earlier.push(item);
    }
  });
  return [data_latest, data_earlier];
}

function generateImgFigure(data, lazy) {
  /*
   * <figure>
   *   <a href="javascript:" target="_blank">
   *     <img src="{{ url_for('static', filename='img/placeholder.png') }}" alt="" referrerpolicy="no-referrer">
   *   </a>
   *   <figcaption>
   *     &ensp;0&nbsp;<i class="fa fa-star"></i>&ensp;
   *     &ensp;<i class="fa fa-arrow-up"></i>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-magic"></i>&nbsp;摄影</a>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-eye"></i>&nbsp;人物</a>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-star"></i>&nbsp;收藏</a>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-ban"></i>&nbsp;R18</a>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-ban"></i>&nbsp;不喜欢</a>&ensp;
   *     &ensp;<a href="javascript:"><i class="fa fa-ban"></i>&nbsp;删除</a>&ensp;
   *     &ensp;<i class="fa fa-tag"></i>&nbsp;标记&ensp;
   *   </figcaption>
   * </figure>
   */
  let figure = $("<figure></figure>");
  let a = $(`<a></a>`);
  if (isPageGuide()) { // 引导页点击封面跳转该图源站点
    a.attr("href", data["srcurl"]);
    // if (new URL(data["srcurl"]).hostname !== location.hostname) { // 非本图源则新开窗口
    //   a.attr("target", "_blank");
    // }
    a.data("rp", data["rawprovider"]).data("ri", data["rawid"]); // 缓存以便 click 事件访问
    a.click(function () { // 通过顶级域名 cookie 传递封面图片ID
      $.cookie(`cover-${$(this).data("rp")}`, $(this).data("ri"), {
        domain: getDomain(),
        path: "/"
      }); // 跨域，无法使用 sessionStorage 或 localStorage
      return true; // 继续响应 href
    });
  } else { // 非引导页点击封面跳转该图片详情页
    // a.attr("href", "/unbox/" + data["id"]);
    a.attr("href", "/flip" + location.pathname);
    a.attr("target", "_blank"); // 新开标签页
    a.data("id", data["id"]); // 缓存以便 click 事件访问
    a.click(function () { // 传递图片集数据
      // 为什么不用 sessionStorage？sessionStorage 同域名有效，但不支持新开标签页
      localStorage.setItem("data", JSON.stringify(DATA_CACHE));
      localStorage.setItem("goto", $(this).data("id"));
      return true; // 继续响应 href
    });
  }
  let img = $(`<img src='' alt='${data["catename"]}' referrerpolicy='no-referrer'>`);
  img.attr("id", data["id"]);
  img.attr("src", PLACEHOLDER);
  if (COVER_FIT === "contain") { // 全图模式
    img.css("object-fit", "contain"); // 覆盖默认 CSS object-fit
  }
  img.data("thumb", data["thumburl"]);
  if (!lazy) { // 立即加载缩略图
    showThumb(img);
  }
  a.append(img);
  figure.append(a);
  let caption = $(`<figcaption></figcaption>"`);
  if (!isPageGuide()) { // 默认常显封面信息，非引导页响应焦点浮动显示
    caption.addClass("fade");
  }
  if (COVER_BLINK) {
    caption.append(`&ensp;${data["blink"]}&nbsp;<i class='fa fa-star'></i>&ensp;`);
    if (data["rank"] > 0) {
      caption.append("&ensp;<i class='fa fa-arrow-up'></i>&ensp;");
    }
  }
  if (URL_API_CATE_HOW && cate_how_id.length > 0) {
    let a = $(`<a id='cate-how-${data["id"]}' href='javascript:'></a>`);
    let cate_index = cate_how_id.indexOf(data["catehowid"]); // 无则为 -1
    let cate_name = cate_how_name[cate_index] ? cate_how_name[cate_index] : "默认";
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"])
      .data("index", cate_index);
    a.append(`&ensp;<i class='fa fa-magic'></i>&nbsp;${cate_name}&ensp;`);
    a.click(function () {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let cate_index = ($(this).data("index") + 1) % cate_how_id.length;
      let cate_id = cate_how_id[cate_index];
      let cate_name = cate_how_name[cate_index];
      $(this).data("index", cate_index);
      $(this).html(`&ensp;<i class='fa fa-magic'></i>&nbsp;${cate_name}&ensp;`);
      clearTimeout(timer_cate_how_id);
      timer_cate_how_id = setTimeout(`markCateHow("${img_id}", "${raw_provider}", "${raw_id}", "${img_url}", "${cate_id}", "${cate_name}")`, 1000);
    });
    caption.append(a);
  }
  if (URL_API_CATE_WHAT && cate_what_id.length > 0) {
    let a = $(`<a id='cate-what-${data["id"]}' href='javascript:'></a>`);
    let cate_index = cate_what_id.indexOf(data["catewhatid"]); // 无则为 -1
    let cate_name = cate_what_name[cate_index] ? cate_what_name[cate_index] : "默认";
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"])
      .data("index", cate_index);
    a.append(`&ensp;<i class='fa fa-eye'></i>&nbsp;${cate_name}&ensp;`);
    a.click(function() {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let cate_index = ($(this).data("index") + 1) % cate_what_id.length;
      let cate_id = cate_what_id[cate_index];
      let cate_name = cate_what_name[cate_index];
      $(this).data("index", cate_index);
      $(this).html(`&ensp;<i class='fa fa-eye'></i>&nbsp;${cate_name}&ensp;`);
      clearTimeout(timer_cate_what_id);
      timer_cate_what_id = setTimeout(`markCateWhat("${img_id}", "${raw_provider}", "${raw_id}", "${img_url}", "${cate_id}", "${cate_name}")`, 1000);
    });
    caption.append(a);
  }
  if (COVER_SAVE) {
    let a = $(`<a id='save-${data["id"]}' href='javascript:'></a>`);
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"]);
    a.append(`&ensp;<i class='fa fa-star'></i>&nbsp;收藏&ensp;`);
    a.click(function() {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let undo = (
        $(this).text().trim() === "收藏" && $(this).children("i").hasClass("fa-check")
      ) || (
        $(this).text().trim() === "撤销" && $(this).children("i").hasClass("fa-times")
      );
      $(this).html(`&ensp;<i class='fa fa-star'></i>&nbsp;${undo ? "撤销" : "收藏"}&ensp;`);
      markSave(img_id, raw_provider, raw_id, img_url, undo);
    });
    caption.append(a);
  }
  if (COVER_R18) {
    let a = $(`<a id='r18-${data["id"]}' href='javascript:'></a>`);
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"]);
    a.append(`&ensp;<i class='fa fa-ban'></i>&nbsp;R18&ensp;`);
    a.click(function() {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let undo = (
        $(this).text().trim() === "R18" && $(this).children("i").hasClass("fa-check")
      ) || (
        $(this).text().trim() === "撤销" && $(this).children("i").hasClass("fa-times")
      );
      $(this).html(`&ensp;<i class='fa fa-ban'></i>&nbsp;${undo ? "撤销" : "R18"}&ensp;`);
      markR18(img_id, raw_provider, raw_id, img_url, undo);
    });
    caption.append(a);
  }
  if (COVER_DISLIKE) {
    let a = $(`<a id='dislike-${data["id"]}' href='javascript:'></a>`);
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"]);
    a.append(`&ensp;<i class='fa fa-ban'></i>&nbsp;不喜欢&ensp;`);
    a.click(function() {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let undo = (
        $(this).text().trim() === "不喜欢" && $(this).children("i").hasClass("fa-check")
      ) || (
        $(this).text().trim() === "撤销" && $(this).children("i").hasClass("fa-times")
      );
      $(this).html(`&ensp;<i class='fa fa-ban'></i>&nbsp;${undo ? "撤销" : "不喜欢"}&ensp;`);
      markDislike(img_id, raw_provider, raw_id, img_url, undo);
    });
    caption.append(a);
  }
  if (COVER_DELETE) {
    let a = $(`<a id='delete-${data["id"]}' href='javascript:'></a>`);
    a.data("id", data["id"])
      .data("rp", parseTag(data, RAW_PROVIDER))
      .data("ri", parseTag(data, RAW_ID))
      .data("url", data["imgurl"]);
    a.append(`&ensp;<i class='fa fa-ban'></i>&nbsp;删除&ensp;`);
    a.click(function() {
      $(this).parent().removeClass("fade"); // 常显封面信息
      let img_id = $(this).data("id");
      let raw_provider = $(this).data("rp");
      let raw_id = $(this).data("ri");
      let img_url = $(this).data("url");
      let undo = (
        $(this).text().trim() === "删除" && $(this).children("i").hasClass("fa-check")
      ) || (
        $(this).text().trim() === "撤销" && $(this).children("i").hasClass("fa-times")
      );
      $(this).html(`&ensp;<i class='fa fa-ban'></i>&nbsp;${undo ? "撤销" : "删除"}&ensp;`);
      markDelete(img_id, raw_provider, raw_id, img_url, undo);
      if (!undo) { // 若未分类，一并设置分类为其他 general
        if ($(`#cate-how-${img_id}`).data("index") < 0) {
          let cate_index = cate_what_id.indexOf("general"); // 无则为 -1
          markCateHow(img_id, raw_provider, raw_id, img_url, "general", cate_what_name[cate_index]);
        }
        if ($(`#cate-what-${img_id}`).data("index") < 0) {
          let cate_index = cate_what_id.indexOf("general"); // 无则为 -1
          markCateWhat(img_id, raw_provider, raw_id, img_url, "general", cate_what_name[cate_index]);
        }
      }
    });
    caption.append(a);
  }
  let tag = parseTag(data, COVER_TAG);
  if (tag) {
    caption.append(`&ensp;<i class='fa fa-tag'></i>&nbsp;${tag}&ensp;`);
  }
  figure.append(caption);
  return figure;
}

function logTotal(data_stats, count) {
  if (DATA_CACHE.length > 0) { // 确保只输出一次
    return;
  }
  if (isPageGuide()) { // 引导页输出图源总览信息
    console.log("\033[43;30m PROVIDERS \033[40;33m " + count + " \033[0m"
      + " \033[46;30m IMAGES \033[40;36m " + data_stats["total"] + " \033[0m");
  } else { // 非引导页输出该图源信息
    console.log("\033[46;30m IMAGES \033[40;36m " + data_stats["total"] + " \033[0m"
      // + " \033[0m" + "\033[46;30m 4K \033[40;36m " + data_stats["4k"] + " \033[0m"
      // + " \033[0m" + "\033[46;30m 8K \033[40;36m " + data_stats["8k"] + " \033[0m"
      // + " \033[0m" + "\033[46;30m BLINK \033[40;36m " + data_stats["blink"] + " \033[0m"
      + " \033[43;30m BPI \033[40;33m " + (data_stats["blink"] / data_stats["total"]).toFixed(1) + " \033[0m");
  }
}

function showThumb(img) {
  if (!img.data("thumb")) { // 已加载，跳过
    return;
  }
  let cache = new Image();
  cache.referrerPolicy = "no-referrer"; // 跨域支持
  cache.onload = function() {
    img.attr("src", $(this).attr("src"));
  };
  cache.onerror = function() { // 可有可无
    img.css("object-fit", "contain").attr("src", LOADING);
  }
  cache.src = img.data("thumb");
  img.removeData("thumb");
}

function showToast(id, icon, msg, action, action_func) {
  /*
   * <div class="toast mb8 collapsed">
   *   <i class="fa fa-exclamation-circle"></i>&nbsp;
   *   <span class="msg"></span>&nbsp;
   *   <a class="action collapsed" href="javascript:">我知道了</a>
   * </div>
   */
  let mask = $(".toast-mask");
  if (!id || !msg) { // 清空消息
    mask.empty();
    return;
  }
  let toast = $(`.toast[data-id="${id}"]`);
  if (toast) { // 移除同类消息
    toast.remove();
  }
  // 构造消息图标
  let toast_icon;
  if (icon === "error") { // 错误
    toast = $("<div class='toast toast-error mb8 collapsed'></div>");
    toast_icon = $("<i class='fa fa-circle-o-notch'></i>")
  } else { // 默认
    toast = $("<div class='toast toast-info mb8 collapsed'></div>");
    toast_icon = $("<i class='fa fa-circle-o'></i>")
  }
  toast.attr("data-id", id);
  // 构造消息内容
  let toast_msg = $("<span class='msg'></span>");
  toast_msg.html(msg.toString().replaceAll("\r\n", "<br>").replaceAll("\n", "<br>"));
  toast.append(toast_icon).append("&nbsp;").append(toast_msg);
  // 构造消息按钮
  if (action) {
    let toast_action = $("<a class='action' href='javascript:'></a>");
    toast_action.html("&nbsp;" + action);
    if (action_func) {
      toast_action.click(function() {
        // closeToast();
        $(this).parents(".toast").remove();
        action_func();
      });
    } else {
      toast_action.click(function() {
        // closeToast();
        $(this).parents(".toast").remove();
      });
    }
    toast.append(toast_action);
  }
  mask.append(toast);
  $(".toast:gt(2)").remove(); // 移除多余消息，保留3条
  toast.show(400);
}

function showToastInfo(id, msg, action, action_func) {
  showToast(id, "info", msg, action, action_func);
}

function showToastError(id, msg, action, action_func) {
  showToast(id, "error", msg, action, action_func);
}

function closeToast() {
  showToast(null, null, null, null, null);
}

function isPageGuide() {
  return PAGE_CURRENT === "/home";
}

function generateApiUrl(url_api, split_key, data_loaded) {
  let user = $.cookie("user") ?? "";
  url_api = url_api.replace("{user}", user);  // 顶级域名共享
  url_api = url_api.replace("{pwd}", $.cookie(`pwd-${user}`) ?? "");  // 顶级域名共享
  url_api = url_api.replace("{device}", $.cookie("fingerprint") ?? "");  // 顶级域名共享
  url_api = url_api.replace("{id}", $.cookie(`cover-${PROVIDER_ID}`) ?? "");
  $.removeCookie(`cover-${PROVIDER_ID}`, { // domain path 需保持一致才能删除
    domain: location.hostname.split(".").slice(-2).join("."),
    path: "/"
  });
  data_loaded = data_loaded.filter(item => !item["extend"]); // 剔除不参与分页计算的元素（浅拷贝）
  if (split_key === "no") {
    let no = data_loaded.length > 0 ?
      data_loaded.sort((a, b) => a["no"] - b["no"])[0]["no"] : 99999999;
    return url_api.replace("{no}", no);
  }
  if (split_key === "score") {
    let score = data_loaded.length > 0 ?
      data_loaded.sort((a, b) => a["score"] - b["score"])[0]["score"] : 99999999;
    return url_api.replace("{score}", score);
  }
  if (split_key === "seed") {
    return url_api.replace("{seed}", Date.now());
  }
  return url_api;
}

function parseLabelEarlier(date_latest) {
  if (!date_latest) {
    return "早些时候";
  }
  const MS_DAY = 24 * 60 * 60 * 1000;
  // 坑1：Chromium 2023-3-24 与 2023-03-24 结果不一样，一个按本地一个按UTC；通过统一加“UTC”解决
  // 坑2：Firefox 2023-3-24 与 2023-03-24 结果一样，但无法识别 2023-03-24 UTC
  let ms_tar = Date.parse(date_latest.replace(/-/g, "/") + " UTC"); // yyyy-MM-dd 不能有时分秒
  let now = new Date();
  let ms_today = Date.parse(`${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()} UTC`);
  if (ms_tar === ms_today) {
    return "一天前";
  }
  let ms_monday = ms_today - (now.getDay() - 1) * MS_DAY;
  if (ms_tar === ms_monday) {
    return "本周之前";
  }
  let days = (ms_today - ms_tar) / MS_DAY;
  if (days === 0) {
    return "今天之前";
  }
  if (days === 1) {
    return "两天前";
  }
  if (days === 2) {
    return "三天前";
  }
  if (days === 6) {
    return "一周前";
  }
  let ms_month = Date.parse(`${now.getFullYear()}-${now.getMonth() + 1}-1 UTC`);
  if (ms_tar === ms_month) {
    return "本月之前";
  }
  if (days > 2 && days < 6) {
    return `${days + 1}天前`;
  }
  return "早些时候";
}

/**
 * 根据图片元数据解析封面标签，若使用元数据字段，使用 {} 标记
 * 例："第{phase}期" >> "第32期"
 */
function parseTag(data, tag) {
  if (!data || !tag) {
    return "";
  }
  function replacer(match, key, len, _offset, _string) {
    let new_val = data[key] ?? "";
    if (!len) {
      return new_val;
    }
    len = parseInt(len);
    if (new_val && new_val.length > len) {
      new_val = new_val.substring(0, len - 2).trim();
      new_val = new_val.replace(/[，。！？…：；“（]+$/g, "").trim();
      new_val += "……";
    }
    return new_val;
  }
  let out = tag.replace(/\{([^}]+?)(?::(\d+))?}/g, replacer);
  return out ?? "";
}

function getDomain() {
  if (["localhost", "127.0.0.1"].indexOf(location.hostname) >= 0) {
    return location.hostname;
  }
  return location.hostname.split(".").slice(-2).join(".");
}

/**
 * 随机一文（每次会话拉取32条）
 * 自动刷新：图库成功加载的前提下，曝光刷新
 * 手动刷新：点击
 */
function refreshGlitter() {
  if (sessionStorage.getItem("glitter")) {
    let glitter = JSON.parse(sessionStorage.getItem("glitter"));
    if (glitter.length > 0) {
      $(".copyright a:first").text(glitter[Date.now() % glitter.length]);
      return;
    }
  }
  // $.cookie("glitter", JSON.stringify([]), { path: "/" }); // 临时设置，避免重复加载
  sessionStorage.setItem("glitter", JSON.stringify([])); // 临时设置，避免重复加载
  fetch("https://api.nguaduot.cn/appstats/glitter?lines=32")
    .then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        let glitter = data["data"];
        $(".copyright a:first").text(glitter[Date.now() % glitter.length]);
        // $.cookie("glitter", JSON.stringify(glitter), { path: "/" }); // 不设置 expires，会话有效
        sessionStorage.setItem("glitter", JSON.stringify(glitter)); // 会话有效
      }
    })
    .catch(console.error);
}

function markCateHow(img_id, raw_provider, raw_id, img_url, cate_id, cate_name) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "catehow",
    target: cate_id,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        // $(`#cate-how-${img_id} i`).removeClass("fa-magic").addClass("fa-check");
        $(`#cate-how-${img_id}`).html(`&ensp;<i class='fa fa-check'></i>&nbsp;${cate_name}&ensp;`);
      } else {
        // $(`#cate-how-${img_id} i`).removeClass("fa-magic").addClass("fa-times");
        $(`#cate-how-${img_id}`).html(`&ensp;<i class='fa fa-times'></i>&nbsp;${cate_name}&ensp;`);
      }
    })
    .catch(console.error);
}

function markCateWhat(img_id, raw_provider, raw_id, img_url, cate_id, cate_name) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "catewhat",
    target: cate_id,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        // $(`#cate-what-${img_id} i`).removeClass("fa-eye").addClass("fa-check");
        $(`#cate-what-${img_id}`).html(`&ensp;<i class='fa fa-check'></i>&nbsp;${cate_name}&ensp;`);
      } else {
        // $(`#cate-what-${img_id} i`).removeClass("fa-eye").addClass("fa-times");
        $(`#cate-what-${img_id}`).html(`&ensp;<i class='fa fa-times'></i>&nbsp;${cate_name}&ensp;`);
      }
    })
    .catch(console.error);
}

function markSave(img_id, raw_provider, raw_id, img_url, undo=false) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "save",
    undo: undo ? 1 : 0,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        $(`#save-${img_id} i`).removeClass("fa-star").addClass("fa-check");
      } else {
        $(`#save-${img_id} i`).removeClass("fa-star").addClass("fa-times");
      }
    })
    .catch(console.error);
}

function markR18(img_id, raw_provider, raw_id, img_url, undo=false) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "r18",
    undo: undo ? 1 : 0,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        $(`#r18-${img_id} i`).removeClass("fa-ban").addClass("fa-check");
      } else {
        $(`#r18-${img_id} i`).removeClass("fa-ban").addClass("fa-times");
      }
    })
    .catch(console.error);
}

function markDislike(img_id, raw_provider, raw_id, img_url, undo=false) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "dislike",
    undo: undo ? 1 : 0,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        $(`#dislike-${img_id} i`).removeClass("fa-ban").addClass("fa-check");
      } else {
        $(`#dislike-${img_id} i`).removeClass("fa-ban").addClass("fa-times");
      }
    })
    .catch(console.error);
}

function markDelete(img_id, raw_provider, raw_id, img_url, undo=false) {
  if (!$.cookie("fingerprint")) {
    return;
  }
  let data_req = {
    provider: raw_provider,
    imgid: raw_id,
    imgurl: img_url,
    action: "delete",
    undo: undo ? 1 : 0,
    deviceid: $.cookie("fingerprint"),
    client: CLIENT
  };
  fetch("https://api.nguaduot.cn/appstats/rank", {
    method: "POST",
    body: JSON.stringify(data_req)
  }).then(response => response.json())
    .then(data => {
      if (data && data["status"] === 1) {
        $(`#delete-${img_id} i`).removeClass("fa-ban").addClass("fa-check");
      } else {
        $(`#delete-${img_id} i`).removeClass("fa-ban").addClass("fa-times");
      }
    })
    .catch(console.error);
}

function checkAccount() {
  let user = $.cookie("user") ?? "";
  let pwd_en = $.cookie(`pwd-${user}`) ?? "";
  let device_id = $.cookie("fingerprint") ?? "";
  if (!user) {
    if (PAGE_CURRENT === "/favorite") {
      showToastError("account", "当前未绑定帐号，您的收藏可能在系统或浏览器更新后丢失。绑定帐号即可使用云端收藏，支持多平台多设备同步。", "绑定…", function() {
        // <a> 不支持 $("#btn-bind").trigger("click");
        $("#btn-bind")[0].click();
      });
    } else if (PAGE_CURRENT === "/seek") {
      showToastError("account", "当前未绑定帐号，建议绑定帐号以获得更佳的「发现」体验。", "绑定…", function() {
        $("#btn-bind")[0].click();
      });
    }
    return;
  }
  let url = `https://api.nguaduot.cn/appstats/account?user=${user}&pwd=${pwd_en}&device=${device_id}`;
  fetch(url)
    .then(response => response.json())
    .then(data => {
      if (!data || data["status"] !== 1) {
        if (PAGE_CURRENT === "/favorite") {
          showToastError("account", "帐号验证失败：" + (data ? data["msg"] : "接口数据异常"));
        }
      } else {
        if (data["data"]["active"] && data["data"]["auth"]) {
          // $("#btn-bind").text("已绑定").removeClass("navbar-more");
          $("#btn-bind").text(data["data"]["user"].substr(0, 4));
        } else {
          if (PAGE_CURRENT === "/favorite") {
            showToastError("account", "当前未绑定帐号，您的收藏可能在系统或浏览器更新后丢失。绑定帐号即可使用云端收藏，支持多平台多设备同步。", "绑定…", function () {
              $("#btn-bind")[0].click();
            });
          } else if (PAGE_CURRENT === "/seek") {
            showToastError("account", "当前未绑定帐号，建议绑定帐号以获得更佳的「发现」体验。", "绑定…", function() {
              $("#btn-bind")[0].click();
            });
          }
        }
      }
    })
    .catch(err => {
      if (PAGE_CURRENT === "/favorite") {
        showToastError("account", "帐号验证失败：" + err);
      }
    });
}

function qcStats() {  // TODO
  let user = $.cookie("user") ?? "";
  if (!user) {
    return;
  }
  let url = `https://api.nguaduot.cn/appstats/qc/stats?user=${user}`;
  fetch(url)
    .then(response => response.json())
    .then(data => {
      if (!data || data["status"] !== 1) {
        showToastError("qc1", "图审统计：" + (data ? data["msg"] : "接口数据异常"));
        return;
      }
      let data_detail = data["data"].sort((a, b) => b["date"].localeCompare(a["date"])); // 日期降序
      let today = `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate()).padStart(2, "0")}`;
      if (data_detail.length > 0) {
        today = data_detail[0]["date"];
      }
      let today_readable = `${new Date(today).getMonth() + 1}月${new Date(today).getDate()}日`;
      let judge_today = 0;
      let judge_mis_today = 0;
      let watermark_today = 0;
      let watermark_mis_today = 0;
      let r18_today = 0;
      let r18_mis_today = 0;
      let delete_today = 0;
      let delete_mis_today = 0;
      let broken_today = 0;
      let broken_mis_today = 0;
      let journal_today = 0;
      let journal_mis_today = 0;
      let rmb_today = 0;
      let judge_history = 0;
      let judge_mis_history = 0;
      let watermark_history = 0;
      let watermark_mis_history = 0;
      let r18_history = 0;
      let r18_mis_history = 0;
      let delete_history = 0;
      let delete_mis_history = 0;
      let broken_history = 0;
      let broken_mis_history = 0;
      let journal_history = 0;
      let journal_mis_history = 0;
      let rmb_history = 0;
      for (let item of data_detail) {
        if (item["date"] === today) {
          judge_today = item["judge"];
          judge_mis_today = item["judge-mis"];
          watermark_today += item["watermark"];
          watermark_mis_today += item["watermark-mis"];
          r18_today += item["r18"];
          r18_mis_today += item["r18-mis"];
          delete_today += item["delete"];
          delete_mis_today += item["delete-mis"];
          broken_today += item["404"];
          broken_mis_today += item["404-mis"];
          journal_today += item["journal"];
          journal_mis_today += item["journal-mis"];
          rmb_today = item["total-rmb"];
        } else {
          judge_history += item["judge"];
          judge_mis_history += item["judge-mis"];
          watermark_history += item["watermark"];
          watermark_mis_history += item["watermark-mis"];
          r18_history += item["r18"];
          r18_mis_history += item["r18-mis"];
          delete_history += item["delete"];
          delete_mis_history += item["delete-mis"];
          broken_history += item["404"];
          broken_mis_history += item["404-mis"];
          journal_history += item["journal"];
          journal_mis_history += item["journal-mis"];
          rmb_history += item["total-rmb"];
        }
      }
      let msg_today = today_readable + "图审：审图" + judge_today + "张"
      if (judge_mis_today > 0) {
        msg_today += "（误判" + judge_mis_today + "张）";
      }
      msg_today += "，水印图" + watermark_today;
      if (watermark_mis_today > 0) {
        msg_today += "（误判" + watermark_mis_today + "）";
      }
      msg_today += "、色图" + r18_today;
      if (r18_mis_today > 0) {
        msg_today += "（误判" + r18_mis_today + "）";
      }
      msg_today += "、低质量图" + delete_today;
      if (delete_mis_today > 0) {
        msg_today += "（误判" + delete_mis_today + "）";
      }
      msg_today += "、损坏图" + broken_today;
      if (broken_mis_today > 0) {
        msg_today += "（误判" + broken_mis_today + "）";
      }
      msg_today += "，好图推荐" + journal_today;
      if (journal_mis_today > 0) {
        msg_today += "（未采纳" + journal_mis_today + "）";
      }
      msg_today += "，预计收益¥" + rmb_today.toFixed(1) + "。";
      msg_today += "（非最终结果，等待管理员复审）"
      let msg_history = today_readable + "之前：审图" + judge_history
      if (judge_mis_history > 0) {
        msg_history += "（误判" + judge_mis_history + "）";
      }
      msg_history += "，水印图" + watermark_history;
      if (watermark_mis_history > 0) {
        msg_history += "（误判" + watermark_mis_history + "）";
      }
      msg_history += "、色图" + r18_history;
      if (r18_mis_history > 0) {
        msg_history += "（误判" + r18_mis_history + "）";
      }
      msg_history += "、低质量图" + delete_history;
      if (delete_mis_history > 0) {
        msg_history += "（误判" + delete_mis_history + "）";
      }
      msg_history += "、损坏图" + broken_history;
      if (broken_mis_history > 0) {
        msg_history += "（误判" + broken_mis_history + "）";
      }
      msg_history += "，好图推荐" + journal_history;
      if (journal_mis_history > 0) {
        msg_history += "（未采纳" + journal_mis_history + "）";
      }
      msg_history += "，收益¥" + rmb_history.toFixed(1) + "。";
      showToastInfo("qc1", msg_today);
      showToastInfo("qc2", msg_history);
    })
    .catch(err => {
      showToastError("qc1", "图审统计：" + err);
    });
}